package es.dmoral.toasty;

import static es.dmoral.toasty.utils.ResUtil.buildDrawableByColor;

import es.dmoral.toasty.utils.DeviceUtils;
import es.dmoral.toasty.utils.ResUtil;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.text.Font;
import ohos.agp.text.RichText;
import ohos.agp.text.RichTextBuilder;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;

public class Toasty {
    private static Font currentTypeface = Font.DEFAULT;
    private static int textSize = 16; // in SP
    private static boolean allowQueue = true;
    private static boolean tintIcon = true;
    private static int orientation = Component.HORIZONTAL;

    public static final int LENGTH_SHORT = 2000;
    public static final int LENGTH_LONG = 3000;

    private Toasty() {
    }

    /* ============================================  normal  ================================================== */

    public static void normal(Context context, int message) {
        normal(context, message, LENGTH_SHORT, null, false);
    }

    public static void normal(Context context, String message) {
        normal(context, message, LENGTH_SHORT, null, false);
    }

    public static void normal(Context context, int message, Element icon) {
        normal(context, message, LENGTH_SHORT, icon, true);
    }

    public static void normal(Context context, String message, Element icon) {
        normal(context, message, LENGTH_SHORT, icon, true);
    }

    public static void normal(Context context, int message, int duration) {
        normal(context, message, duration, null, false);
    }

    public static void normal(Context context, String message, int duration) {
        normal(context, message, duration, null, false);
    }

    public static void normal(Context context, int message, int duration, Element icon) {
        normal(context, message, duration, icon, true);
    }

    public static void normal(Context context, String message, int duration, Element icon) {
        normal(context, message, duration, icon, true);
    }

    public static void normal(Context context, int message, int duration, Element icon, boolean withIcon) {
        custom(
                context,
                ResUtil.getString(context, message),
                icon,
                ResourceTable.Color_normalColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    public static void normal(Context context, String message, int duration, Element icon, boolean withIcon) {
        custom(
                context,
                message,
                icon,
                ResourceTable.Color_normalColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    /* ============================================  warning  ================================================== */
    public static void warning(Context context, int message) {
        warning(context, message, LENGTH_SHORT, true);
    }

    public static void warning(Context context, String message) {
        warning(context, message, LENGTH_SHORT, true);
    }

    public static void warning(Context context, int message, int duration) {
        warning(context, message, duration, true);
    }

    public static void warning(Context context, String message, int duration) {
        warning(context, message, duration, true);
    }

    public static void warning(Context context, int message, int duration, boolean withIcon) {
        custom(
                context,
                ResUtil.getString(context, message),
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_info_outline_white_24dp),
                ResourceTable.Color_warningColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    public static void warning(Context context, String message, int duration, boolean withIcon) {
        custom(
                context,
                message,
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_error_outline_white_24dp),
                ResourceTable.Color_warningColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    /* ============================================  info  ================================================== */

    public static void info(Context context, int message) {
        info(context, message, LENGTH_SHORT, true);
    }

    public static void info(Context context, String message) {
        info(context, message, LENGTH_SHORT, true);
    }
    public static void info(Context context, RichText message) {
        info(context, message, LENGTH_SHORT, true);
    }

    public static void info(Context context, int message, int duration) {
        info(context, message, duration, true);
    }

    public static void info(Context context, String message, int duration) {
        info(context, message, duration, true);
    }

    public static void info(Context context, int message, int duration, boolean withIcon) {
        custom(
                context,
                ResUtil.getString(context, message),
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_info_outline_white_24dp),
                ResourceTable.Color_infoColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }
    public static void info(Context context, RichText message, int duration, boolean withIcon) {
        custom(
                context,
                message,
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_info_outline_white_24dp),
                ResourceTable.Color_infoColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    public static void info(Context context, String message, int duration, boolean withIcon) {
        custom(
                context,
                message,
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_info_outline_white_24dp),
                ResourceTable.Color_infoColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    /* ============================================  success  ================================================== */

    public static void success(Context context, int message) {
        success(context, message, LENGTH_SHORT, true);
    }

    public static void success(Context context, String message) {
        success(context, message, LENGTH_SHORT, true);
    }

    public static void success(Context context, int message, int duration) {
        success(context, message, duration, true);
    }

    public static void success(Context context, String message, int duration) {
        success(context, message, duration, true);
    }

    public static void success(Context context, int message, int duration, boolean withIcon) {
        custom(
                context,
                ResUtil.getString(context, message),
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_check_white_24dp),
                ResourceTable.Color_successColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    public static void success(Context context, String message, int duration, boolean withIcon) {
        custom(
                context,
                message,
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_check_white_24dp),
                ResourceTable.Color_successColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    /* ============================================  error  ================================================== */
    public static void error(Context context, int message) {
        error(context, message, LENGTH_SHORT, true);
    }

    public static void error(Context context, String message) {
        error(context, message, LENGTH_SHORT, true);
    }

    public static void error(Context context, int message, int duration) {
        error(context, message, duration, true);
    }

    public static void error(Context context, String message, int duration) {
        error(context, message, duration, true);
    }

    public static void error(Context context, int message, int duration, boolean withIcon) {
        custom(
                context,
                ResUtil.getString(context, message),
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_clear_white_24dp),
                ResourceTable.Color_errorColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    public static void error(Context context, String message, int duration, boolean withIcon) {
        custom(
                context,
                message,
                ResUtil.getVectorDrawable(context, ResourceTable.Graphic_ic_clear_white_24dp),
                ResourceTable.Color_errorColor,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                true);
    }

    /* ============================================  custom  ================================================== */
    public static void custom(Context context, int message, Element icon, int duration, boolean withIcon) {
        custom(
                context,
                ResUtil.getString(context, message),
                icon,
                -1,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                false);
    }

    public static void custom(Context context, String message, Element icon, int duration, boolean withIcon) {
        custom(context, message, icon, -1, ResourceTable.Color_defaultTextColor, duration, withIcon, false);
    }

    public static void custom(
            Context context,
            int message,
            int iconRes,
            int tintColorRes,
            int duration,
            boolean withIcon,
            boolean shouldTint) {
        custom(
                context,
                ResUtil.getString(context, message),
                ResUtil.getDrawable(context, iconRes),
                tintColorRes,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                shouldTint);
    }

    public static void custom(
            Context context,
            String message,
            int iconRes,
            int tintColorRes,
            int duration,
            boolean withIcon,
            boolean shouldTint) {
        custom(
                context,
                message,
                ResUtil.getDrawable(context, iconRes),
                tintColorRes,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                shouldTint);
    }

    public static void custom(
            Context context,
            int message,
            Element icon,
            int tintColorRes,
            int duration,
            boolean withIcon,
            boolean shouldTint) {
        custom(
                context,
                ResUtil.getString(context, message),
                icon,
                tintColorRes,
                ResourceTable.Color_defaultTextColor,
                duration,
                withIcon,
                shouldTint);
    }

    public static void custom(
            Context context,
            int message,
            Element icon,
            int tintColorRes,
            int textColorRes,
            int duration,
            boolean withIcon,
            boolean shouldTint) {
        custom(
                context,
                ResUtil.getString(context, message),
                icon,
                tintColorRes,
                textColorRes,
                duration,
                withIcon,
                shouldTint);
    }
    public static void custom(
            Context context,
            RichText message,
            Element icon,
            int tintColor,
            int textColor,
            int duration,
            boolean withIcon,
            boolean shouldTint) {
        LayoutScatter scatter = LayoutScatter.getInstance(context);
        DirectionalLayout mContainer =
                (DirectionalLayout) scatter.parse(ResourceTable.Layout_toast_layout, null, false);
        mContainer.setOrientation(orientation);

        final Image toastIcon = (Image) mContainer.findComponentById(ResourceTable.Id_toast_icon);
        final Text toastText = (Text) mContainer.findComponentById(ResourceTable.Id_toast_text);
        toastText.setRichText(message);
        toastText.setFont(currentTypeface);
        toastText.setTextSize(textSize, Text.TextSizeType.FP);
        toastText.setTextColor(new Color(ResUtil.getColor(context, textColor)));
        toastText.setMultipleLine(true);
        if (mContainer.getOrientation() == Component.VERTICAL) {
            toastText.setMarginBottom(DeviceUtils.dp2px(context, 5));
        }

        ShapeElement rootBackgroud = null;
        if (shouldTint) {
            rootBackgroud = (ShapeElement) buildDrawableByColor(ResUtil.getColor(context, tintColor));
        } else {
            rootBackgroud = (ShapeElement) buildDrawableByColor(Color.getIntColor("#f5f5f5")); // f5f5f5
        }
        rootBackgroud.setCornerRadius(30);
        Component content = mContainer.findComponentById(ResourceTable.Id_toast_layout_root);
        content.setBackground(rootBackgroud);

        if (withIcon) {
            if (icon == null) {
                throw new IllegalArgumentException("Avoid passing 'icon' as null if 'withIcon' is set to true");
            }
            if (icon instanceof PixelMapElement) {
                toastIcon.setPixelMap(((PixelMapElement) icon).getPixelMap());
            } else {
                toastIcon.setImageElement(icon);
            }
        } else {
            toastIcon.setVisibility(Component.HIDE);
        }

        ToastDialog currentToast = new ToastDialog(context);
        currentToast.setContentCustomComponent(mContainer)
                .setDuration(duration)
                .setSize(DirectionalLayout.LayoutConfig.MATCH_PARENT, DirectionalLayout.LayoutConfig.MATCH_PARENT)
                .setAutoClosable(true)
                .setTransparent(true).show();
    }
    public static void custom(
            Context context,
            String message,
            Element icon,
            int tintColor,
            int textColor,
            int duration,
            boolean withIcon,
            boolean shouldTint) {
        LayoutScatter scatter = LayoutScatter.getInstance(context);
        DirectionalLayout mContainer =
                (DirectionalLayout) scatter.parse(ResourceTable.Layout_toast_layout, null, false);
        mContainer.setOrientation(orientation);

        final Image toastIcon = (Image) mContainer.findComponentById(ResourceTable.Id_toast_icon);
        final Text toastText = (Text) mContainer.findComponentById(ResourceTable.Id_toast_text);
        toastText.setText(message);
        toastText.setFont(currentTypeface);
        toastText.setTextSize(textSize, Text.TextSizeType.FP);
        toastText.setTextColor(new Color(ResUtil.getColor(context, textColor)));
        toastText.setMultipleLine(true);
        if (mContainer.getOrientation() == Component.VERTICAL) {
            toastText.setMarginBottom(DeviceUtils.dp2px(context, 5));
        }

        ShapeElement rootBackgroud = null;
        if (shouldTint) {
            rootBackgroud = (ShapeElement) buildDrawableByColor(ResUtil.getColor(context, tintColor));
        } else {
            rootBackgroud = (ShapeElement) buildDrawableByColor(Color.getIntColor("#f5f5f5")); // f5f5f5
        }
        rootBackgroud.setCornerRadius(30);
        Component content = mContainer.findComponentById(ResourceTable.Id_toast_layout_root);
        content.setBackground(rootBackgroud);

        if (withIcon) {
            if (icon == null) {
                throw new IllegalArgumentException("Avoid passing 'icon' as null if 'withIcon' is set to true");
            }
            if (icon instanceof PixelMapElement) {
                toastIcon.setPixelMap(((PixelMapElement) icon).getPixelMap());
            } else {
                toastIcon.setImageElement(icon);
            }
        } else {
            toastIcon.setVisibility(Component.HIDE);
        }

        ToastDialog currentToast = new ToastDialog(context);
        currentToast.setContentCustomComponent(mContainer)
                .setDuration(duration)
                .setSize(DirectionalLayout.LayoutConfig.MATCH_PARENT, DirectionalLayout.LayoutConfig.MATCH_PARENT)
                .setAutoClosable(true)
                .setTransparent(true).show();
    }

    /* ============================================  custom  ================================================== */

    public static class Config {
        private Font typeface = Toasty.currentTypeface;
        private int textSize = Toasty.textSize;
        private boolean tintIcon = Toasty.tintIcon;
        private boolean allowQueue = true;
        private int orientation = Toasty.orientation;

        private Config() {
            // avoiding instantiation
        }

        public static Config getInstance() {
            return new Config();
        }

        public static void reset() {
            Toasty.currentTypeface = Font.DEFAULT;
            Toasty.textSize = 16;
            Toasty.tintIcon = true;
            Toasty.allowQueue = true;
        }

        public Config setTextSize(int sizeInSp) {
            this.textSize = sizeInSp;
            return this;
        }

        public Config setTextFont(Font textFont) {
            this.typeface = textFont;
            return this;
        }

        public Config tintIcon(boolean tintIcon) {
            this.tintIcon = tintIcon;
            return this;
        }

        public Config allowQueue(boolean allowQueue) {
            this.allowQueue = allowQueue;
            return this;
        }

        public void apply() {
            Toasty.currentTypeface = typeface;
            Toasty.textSize = textSize;
            Toasty.tintIcon = tintIcon;
            Toasty.allowQueue = allowQueue;
        }
    }
}
